<template>
	<view class="share">
		<HeaderBar title="Approve授权检测" showBack fixed>
			<template #right>
			</template>
		</HeaderBar>
		<view class="contentBox" :timeId="timeId" :change:timeId="renderjs.approve" :initdata="initdata"
			:change:initdata="renderjs.getalldata">
			<!-- <view class="input">
				<uni-easyinput v-model="value" primaryColor="#333" clearSize="20" :styles="styles"
					:placeholderStyle="placeholderStyle" placeholder="请输入您的地址"></uni-easyinput>
				<view class="btn">
					确认
				</view>
			</view> -->
			<view class="tilp">
				温馨提示：一般不限量的授权都伴随着巨大风险，建议您可以取消授权，也可以在进行授权的时候修改授权数量。
			</view>
			<view class="list">
				<view class="li" v-for="(item,index) in list" :key="index">
					<view class="head">
						<image :src="'/static/images/tokenicon/'+token+chainInfo.chainType+chainInfo.chainId+'.png'"
							mode="" class="icon" @error="imageError(item)" v-if="!item.err"></image>
						<image src="/static/images/notoken.png" mode="widthFix" class="icon" v-show="item.err"></image>
						<view class="name">
							{{symbol}}
						</view>
						(<view class="address">
							{{$utils.formatAddress(token)}}
						</view>
						<image src="/static/images/home/copy.png" mode="" class="copy" @tap="copy(token)">
						</image>)
					</view>
					<view class="data-info">
						<view class="data-info-item">
							<view class="name">
								授权地址:
							</view>
							<view class="address">
								{{$utils.formatAddress(item.address)}}
							</view>
						</view>
						<view class="data-info-item">
							<view class="name">
								授权数量:
							</view>
							<view class="number">
								{{amount(item.num,decimal)}}
							</view>
						</view>
						<view class="btn" :data-toAddress="item.address" :data-token="token" :data-erc20="erc20"
							:data-rpc="rpc" :data-privateKey="privateKey" :data-symbol="symbol" @tap="renderjs.getGas">
							取消授权
						</view>
					</view>
				</view>
				<zanwei style="margin-top:80upx" type="2" v-if="list.length==0"></zanwei>
			</view>

		</view>
		<uni-popup ref="popup" type="bottom" background-color="#FFFFFF" border-radius="10px 10px 0 0">
			<view class="popupTitle">
				交易详情
				<!-- <text class="iconfont icon-guanbi"></text> -->
			</view>
			<view class="numberBox">
				<view class="number">
					申请取消代币{{symbol}}转账授权
				</view>
			</view>
			<view class="fromAddress">
				<view class="left">
					付款地址
				</view>
				<view class="right">
					<view class="address">
						{{$utils.formatAddress(address)}}
					</view>
				</view>
			</view>
			<view class="toAddress borderT ">
				<view class="left">
					收款地址
				</view>
				<view class="right">
					<view class="address">
						{{$utils.formatAddress(toAddress)}}
					</view>
					<!-- <text class="chain" v-if="name">({{name}})</text> -->
				</view>
			</view>

			<view class="toAddress borderT borderB">
				<view class="left">
					网络费
				</view>
				<view class="right">
					<view class="address">
						{{fee}} {{getTokenymbol}}
					</view>
					<!-- <view class="address" v-if="addressInfo.chainType=='TRON'">
						≈ {{trxestimatedFee}} TRX
					</view> -->
					<text class="chain" v-if="addressInfo.chainType=='ETH'">=Gas Limit({{gasLimit}})*Gas
						Price({{Number(Number(gasPrice).toFixed(4))}} Gwei)</text>
				</view>
			</view>
			<view class="popupBtn">
				<view class="pbtn quxiaopth" @tap="cancel">
					取消
				</view>
				<view class="pbtn" @tap="pass">
					确定
				</view>
			</view>
		</uni-popup>
		<PasswordPopup ref="passwordPopup" @close="close" @confirm="confirm" />
	</view>
</template>

<script>
	export default {
		data() {
			return {
				placeholderStyle: "color:#B2B2B2;font-size:28upx",
				styles: {
					color: '#333',
					borderColor: '#eee',
				},
				list: [],
				address: "",
				toAddress: "",
				token: "",
				symbol: "",
				fee: "",
				gasLimit: "",
				gasPrice: "",
				timeIdinfo: "",
				timeId: "",
				decimal: 18,
			}
		},
		computed: {
			initdata() {
				return {
					token: this.token,
					address: this.$store.getters.getAddress,
					rpc: this.rpc,
					privateKey: this.privateKey,
					erc20: this.erc20
				}
			},
			chainInfo() {
				return this.$store.getters.chainInfo
			},
			getTokenymbol() {
				return this.$store.getters.tokensymbol
			},
			chainId() {
				return this.$store.getters.getChainId;
			},
			addressInfo() {
				return this.$store.getters.addressInfo
			},
			privateKey() {
				if (!this.addressInfo) {
					return ""
				}
				return this.addressInfo.privateKey
			},
			rpc() {
				return this.$store.getters.getRpc
			},
			erc20() {
				return this.$config.erc20
			},
		},
		onLoad(options) {
			this.token = options.token || ""
			this.symbol = options.symbol || ""
			this.decimal = options.decimal || ""
		},
		mounted() {},
		methods: {
			amount(amount, decimal) {
				// 将 amount 转换为数组，方便处理
				const amountArray = amount.split('');
				// 如果 decimal 大于 amount 的长度，则结果为 0
				if (decimal > amount.length) {
					const zerosToAdd = decimal - amount.length;
					return '0.' + '0'.repeat(zerosToAdd) + amount;
				}
				// 找到小数点的位置
				const pointIndex = amount.length - decimal;
				// 插入小数点
				amountArray.splice(pointIndex, 0, '.');
				// 去掉末尾的零
				while (amountArray[amountArray.length - 1] === '0') {
					amountArray.pop();
				}
				// 如果最后一个字符是小数点，也去掉
				if (amountArray[amountArray.length - 1] === '.') {
					amountArray.pop();
				}
				// 返回结果
				if (amountArray.join('') > 100000000) {
					return "无限制"
				}
				return amountArray.join('');
			},
			imageError(item) {
				this.$set(item, 'err', true);
			},
			cancel() {
				this.$refs.popup.close()
			},
			pass() {
				this.$refs.passwordPopup.open()
			},
			close() {
				this.$refs.passwordPopup.close()
			},
			showLoading() {
				uni.showLoading({
					title: '加载中',
					mask: true,
				});
			},
			hideLoading() {
				uni.hideLoading()
			},
			confirm() {
				this.timeId = this.timeIdinfo
				this.cancel()
				this.close()
			},
			getInfo(list) {
				this.list = list
			},
			getFee(info) {
				this.address = info.address
				this.toAddress = info.toAddress
				this.symbol = info.symbol
				this.fee = info.fee
				this.gasPrice = info.gasPrice
				this.gasLimit = info.gasLimit
				this.timeIdinfo = info.timeId
				this.$refs.popup.open()
			},
			error(tip) {
				uni.showToast({
					title: tip,
					position: "bottom",
					icon: "none",
					duration: 2000
				});
			},
			copy(address) {
				uni.setClipboardData({
					data: address,
					success: () => {
						uni.showToast({
							title: '复制成功',
							icon: 'none',
						});
					},
					fail: () => {
						uni.showToast({
							title: '复制失败',
							icon: 'none',
						});
					},
				});
			}
		}
	}
</script>

<script module="renderjs" lang="renderjs">
	export default {
		data() {
			return {
				jsLoadState: false,
				// 要执行的合约信息
				dataStr: "",
				// 要执行的合约ID
				timeId: "",
				chainId: "",
				rpc: "",
				privateKey: "",
				// 同步过来的初始化数据
				initdata: {},

			}
		},
		mounted() {
			const ethersScript = document.createElement('script');
			ethersScript.src = 'static/script/ethers-5.2.umd.min.js';
			ethersScript.onload = async () => {
				this.jsLoadState = true;
				if (this.initdata) {
					this.getList()
				}
			};
			document.head.appendChild(ethersScript);
		},
		methods: {
			// 同步数据
			getalldata(newValue) {
				if (newValue) {
					this.initdata = newValue
					if (this.jsLoadState == true) {
						this.getList()

					}
				}
			},
			//获取授权列表
			async getList() {
				if (!this.initdata.rpc || !this.initdata.privateKey || !this.initdata.token || !this.initdata.erc20) {
					return
				}
				this.$ownerInstance.callMethod('showLoading')
				try {
					// 创建提供者和钱包实例
					const provider = new ethers.providers.JsonRpcProvider(this.initdata.rpc);
					const wallet = new ethers.Wallet(this.initdata.privateKey, provider);
					const address = wallet.address;
					// 创建合约实例
					const contract = new ethers.Contract(this.initdata.token, this.initdata.erc20, wallet);
					// 获取当前区块高度
					const latestBlock = await provider.getBlockNumber();
					// 定义过滤器
					const filter = contract.filters.Approval(address, null, null);
					// 查询事件
					const events = await contract.queryFilter(filter, 0, latestBlock);
					// 将授权过的地址生成一个新的地址组，并做好去重
					const addresslist = new Set(); // 使用 Set 来自动去重
					for (let i = 0; i < events.length; i++) {
						addresslist.add(events[i].args[1]);
					}
					// 最终的授权记录，去掉授权数量已经为0的地址
					const approvelist = [];
					for (const addr of addresslist) {
						try {
							const allowancenum = await contract.allowance(address, addr);
							if (allowancenum.gt(0)) { // 使用 ethers.js 的 BigNumber 比较
								approvelist.push({
									address: addr,
									num: allowancenum.toString() // 转换为字符串
								});
							}
						} catch (error) {
							// console.error(`Error checking allowance for address ${addr}:`, error);
						}
					}
					// 结果如下，这里面有两点我没做处理一个是获取小数位，一个是数量转换
					this.$ownerInstance.callMethod('getInfo', approvelist);
					this.$ownerInstance.callMethod('hideLoading')
				} catch (error) {
					this.$ownerInstance.callMethod('hideLoading')
					// console.error('Error in getApprovalList:', error);
					return this.$ownerInstance.callMethod('error', "获取失败")
				}
			},
			//预约执行获取手续费
			async getGas(e) {
				let toAddress = e.target.dataset.toAddress
				let token = e.target.dataset.token
				let erc20 = e.target.dataset.erc20
				this.chainId = e.target.dataset.chainId
				this.rpc = e.target.dataset.rpc
				this.privateKey = e.target.dataset.privateKey
				let symbol = e.target.dataset.symbol
				if (this.jsLoadState) {
					this.$ownerInstance.callMethod('showLoading')
					try {
						const provider = new ethers.providers.JsonRpcProvider(this.rpc);
						const wallet = new ethers.Wallet(this.privateKey, provider);
						let address = wallet.address
						// 获取当前 gas 价格
						const gasPrice = await provider.getGasPrice();
						// 创建合约实例
						const contract = new ethers.Contract(token, erc20, wallet);
						// 预估调用 approve 方法所需的 gas
						const gasLimit = await contract.estimateGas.approve(toAddress, "0");
						//计算手续费
						const estimatedFee = gasPrice.mul(gasLimit);
						const timeId = Date.now()
						this.dataStr = await contract.populateTransaction.approve(toAddress, "0")
						//
						let info = {
							address,
							toAddress,
							symbol,
							gasLimit: gasLimit.toString(),
							gasPrice: ethers.utils.formatUnits(gasPrice, "gwei"),
							fee: ethers.utils.formatUnits(estimatedFee, "ether"),
							timeId
						}

						this.timeId = timeId
						this.$ownerInstance.callMethod('getFee', info);
					} catch (e) {
						return this.$ownerInstance.callMethod('error', "合约执行失败")
					}
				}
				this.$ownerInstance.callMethod('hideLoading')
			},
			async approve(newValue) {
				if (newValue && newValue == this.timeId) {
					this.$ownerInstance.callMethod('showLoading')
					try {
						let provider = new ethers.providers.JsonRpcProvider(this.rpc);
						let signer = new ethers.Wallet(this.privateKey, provider);
						let res = await signer.sendTransaction(this.dataStr)
						let calldata = await provider.waitForTransaction(res.hash);
						if (calldata.status == 1) {
							this.getList()
							this.$ownerInstance.callMethod("error", '合约请求成功')
						}
					} catch (e) {
						this.$ownerInstance.callMethod('error', "合约执行失败")
					}
					this.$ownerInstance.callMethod('hideLoading')
				}
			}
		},
	}
</script>

<style scoped lang="scss">
	.share {
		height: 100%;
		display: flex;
		flex-direction: column;

		.contentBox {
			padding: 30upx 0;

			.input {
				display: flex;
				align-items: center;
				padding: 0 40upx;

				.btn {
					display: flex;
					align-items: center;
					margin: 0 20upx;
					height: 70upx;
					padding: 0 30upx;
					border-radius: 10upx;
					background: linear-gradient(#B1F19B, #1D6E09);
					color: #FFF;
					font-size: 24upx;
				}
			}

			.tilp {
				margin: 30upx 0;
				padding: 30upx;
				font-size: 24upx;
				background: #FFEDED;
				color: #DF6556;
			}

			.list {
				padding: 0 40upx;

				.li {
					box-shadow: 0 4px 10px 0 rgba(0, 0, 0, .12);
					border-radius: 20upx;
					margin-bottom: 20upx;

					.head {
						display: flex;
						align-items: center;
						font-size: 26upx;
						color: #333;
						padding: 20upx 30upx;
						border-bottom: 0.5px solid #eee;

						.icon {
							width: 56upx;
							height: 56upx;
							border-radius: 50%;
						}

						.name {
							margin-left: 20upx;
							margin-right: 10upx;
						}

						.address {
							margin-right: 10upx;
						}

						.copy {
							width: 40upx;
							height: 40upx;
						}
					}

					.data-info {
						padding-bottom: 30upx;

						.data-info-item {
							display: flex;
							align-items: center;
							font-size: 24upx;
							padding: 20upx 30upx 0;

							.name {
								color: #666;
								margin-right: 20upx;
							}

						}

						.btn {
							margin: 30upx 30upx 0;
							text-align: center;
							border: 1px solid #eee;
							font-size: 24upx;
							padding: 20upx 0;
							border-radius: 33upx;
						}
					}
				}
			}
		}

		.uni-form-item {
			width: 100%;

			.input-wrapper {
				display: flex;
				// height: 70upx;
				background: #FFFFFF;
				padding: 0 20upx;
				border: 1upx solid #999999;
				align-items: center;
				border-radius: 10upx;

				.uni-input {
					flex: 1;
				}

				.icon {
					width: 32upx;
					height: 32upx;
				}
			}
		}

		.popupTitle {
			text-align: center;
			position: relative;
			height: 110upx;
			line-height: 110upx;
			font-size: 36upx;
			border-bottom: 1upx solid #D8D8D8;

			.iconfont {
				position: absolute;
				right: 30upx;
			}
		}

		.numberBox {
			padding: 0 56upx;
			margin-top: 32upx;

			.number {
				width: 100%;
				text-align: center;
				font-size: 36upx;
				color: #3D3D3D;
				background: #F5F6F8;
				border-radius: 12upx;
				line-height: 96upx;
			}
		}

		.toAddress {
			margin-top: 0;
		}

		.borderT {
			border-top: 1upx solid #D8D8D8;
		}

		.borderB {
			border-bottom: 1upx solid #D8D8D8;
		}

		.fromAddress,
		.toAddress {
			padding: 54upx 54upx 52upx;
			font-size: 28upx;
			display: flex;

			.left {
				color: #999999;
				width: 152upx;
			}

			.right {
				.address {
					color: #3D3D3D;
				}

				.chain {
					color: #999999;
					font-size: 20upx;
				}
			}
		}

		.popupBtn {
			padding: 30upx 40upx;
			display: flex;
			justify-content: space-between;

			.pbtn {
				font-size: 26upx;
				color: #F6F6F6;
				line-height: 88upx;
				background: linear-gradient(180deg, #A9E993 0%, #368321 100%);
				border-radius: 10upx;
				text-align: center;
				width: 46%;
			}

			.quxiaopth {
				background: #FFBC42 !important;
			}
		}
	}
</style>